from celery import current_app as celery_app
#因为前端页面，多引入了依赖 render_template
from flask import Blueprint, jsonify, send_file, request, abort, make_response, redirect, url_for, current_app, render_template
from datetime import date, datetime
import io
import pandas as pd
import zipfile
from .models import ScheduleResult, Elderdemand, TimeSlot, DicNursingAction, Attendantskills, CaregiverSchedule, db, ShiftAssignment
from .scheduler import Plan
from config_params import params
from sqlalchemy import func
from .redis_utils import get_redis_connection
from .redis_utils import get_update_time
from .shift_scheduler import ShiftScheduler  # 导入新的三班排班处理类
import json

main = Blueprint('main', __name__)

"""
主页路由 - 显示欢迎信息
功能: 提供API的欢迎页面
返回: 简单的欢迎文本
"""
@main.route('/')
def index():
    return "Welcome to the Nursing Schedule App!"

"""
测试成功： http://192.168.10.29:10334/check_update
Redis状态检查路由 - 检查系统是否更新完成
功能: 从Redis获取更新标志, 用于前端判断系统是否正在生成新的排班
返回: update值为"1"表示系统已更新, 如果没有设置则表示未连接上Redis或其他情况
"""
@main.route('/check_update', methods=['GET'])
def check_update():
    redis_conn = get_redis_connection()
    if redis_conn:
        update_value = redis_conn.get(current_app.config['REDIS_UPDATE_KEY'])
        return jsonify({"update": update_value})
    else:
        return jsonify({"error": "无法连接到Redis"}), 500

"""
测试成功： http://192.168.10.29:10334/last_update_time
获取最后更新时间路由 - 返回系统最后一次更新的时间戳
功能: 从Redis获取最后一次排班生成的时间
返回: 包含时间戳的JSON对象
"""
@main.route('/last_update_time', methods=['GET'])
def get_last_update_time():
    last_update_time = get_update_time()
    if last_update_time:
        return jsonify({"last_update_time": last_update_time})
    else:
        return jsonify({"error": "无法获取最后更新时间"}), 404

"""
生成和保存排班表路由
功能: 运行排班算法并将结果保存到数据库
方法:
- POST: 生成新的排班表并保存到数据库, 返回: 包含时间段编号和护理员在该时间段可用性的JSON数组
- GET: 生成排班后重定向到查看排班表页面
"""
@main.route('/generate_and_save_schedule', methods=['GET', 'POST'])
def generate_and_save_schedule():
    plan = Plan(params)
    client_schedules = plan.run()

    if request.method == 'POST':
        return jsonify({"message": "Schedules generated and saved successfully", "date": datetime.now().isoformat()})
    else:
        return redirect(url_for('main.view_schedule'))

"""
测试成功： http://192.168.10.29:10334/caregiver_schedule/15?date=2025-03-07
获取护理人员排班路由 - 查询特定护理人员在指定日期的排班情况
功能: 获取指定护理人员在特定日期的时间段可用性
参数:
- caregiver_id: 护理人员ID
- date: 日期(可选, 默认今天)
返回: 包含护理员可用性和时间段的JSON数组
"""
@main.route('/caregiver_schedule/<string:caregiver_id>', methods=['GET'])
def get_caregiver_schedule(caregiver_id):
    schedule_date_str = request.args.get('date', date.today().isoformat())
    schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()

    schedules = CaregiverSchedule.query.filter(
        CaregiverSchedule.caregiver_id == caregiver_id,
        func.date(CaregiverSchedule.schedule_date) == schedule_date
    ).order_by(CaregiverSchedule.time_slot).all()

    return jsonify([{
        'time_slot': schedule.time_slot,
        'is_available': schedule.is_available
    } for schedule in schedules])

"""
测试成功： http://192.168.10.29:10334/update_caregiver_availability
更新护理人员可用性路由 - 更新护理人员在特定时间段的可用状态
功能: 设置或更新护理人员在特定日期和时间段的可用性
方法: POST
数据格式: JSON, 包含caregiver_id, date, time_slot, is_available
返回: 成功或错误信息
"""
@main.route('/update_caregiver_availability', methods=['POST'])
def update_caregiver_availability():
    data = request.json
    caregiver_id = data.get('caregiver_id')
    schedule_date_str = data.get('date')
    time_slot = data.get('time_slot')
    is_available = data.get('is_available')

    if not all([caregiver_id, schedule_date_str, time_slot is not None, is_available is not None]):
        return jsonify({'error': 'Missing required data'}), 400

    schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()

    schedule = CaregiverSchedule.query.filter_by(
        caregiver_id=caregiver_id,
        schedule_date=schedule_date,
        time_slot=time_slot
    ).first()

    if schedule:
        schedule.is_available = is_available
    else:
        new_schedule = CaregiverSchedule(
            caregiver_id=caregiver_id,
            schedule_date=schedule_date,
            time_slot=time_slot,
            is_available=is_available
        )
        db.session.add(new_schedule)

    try:
        db.session.commit()
        return jsonify({'message': 'Caregiver availability updated successfully'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

"""
测试成功-查看所有老人当天的排班: http://192.168.10.29:10334/view_schedule
测试成功-查看特定日期所有老人的排班:  http://192.168.10.29:10334/view_schedule?date=2025-03-07
测试成功-查看特定老人当天的排班: http://192.168.10.29:10334/view_schedule?elder=3449
测试成功-查看特定老人在特定日期的排班: http://192.168.10.29:10334/view_schedule?elder=3449&date=2025-03-07
测试成功-
可选： ?elder=15&date=2025-03-07
查看排班表路由 - 获取指定老人或所有老人的排班信息
功能: 查询数据库中保存的排班结果
参数:
- elder: 老人ID(可选, 如不提供则返回所有老人的排班)
- date: 日期(可选, 默认今天)
返回: 包含排班详情的JSON对象
"""
@main.route('/view_schedule', methods=['GET'])
def view_schedule():
    elder = request.args.get('elder')
    schedule_date_str = request.args.get('date', date.today().isoformat())
    schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()

    def process_time_slot(ts):
        return {
            'id': ts.id,
            'elder': ts.elder,
            'time_slot': ts.time_slot,
            'activity': ts.activity,
            'activity_id': ts.activity_id,
            'caregiver': 'lack' if ts.caregiver_id == '-1' else ts.caregiver,
            'caregiver_id': ts.caregiver_id,
            'schedule_date': ts.schedule_date.isoformat()
        }

    try:
        if elder:
            schedule_result = ScheduleResult.query.filter(
                ScheduleResult.elder == elder,
                db.func.date(ScheduleResult.schedule_date) == schedule_date
            ).first()
            if schedule_result:
                time_slots = TimeSlot.query.filter_by(schedule_result_id=schedule_result.id).order_by(
                    TimeSlot.time_order).all()
                return jsonify({
                    'elder': elder,
                    'schedule_date': schedule_date.isoformat(),
                    'json_data': schedule_result.schedule_data,
                    'time_slots': [process_time_slot(ts) for ts in time_slots]
                })
            else:
                return jsonify({'error': 'Schedule not found'}), 404
        else:
            all_schedules = ScheduleResult.query.filter(db.func.date(ScheduleResult.schedule_date) == schedule_date).all()
            grouped_schedules = {}
            for sr in all_schedules:
                elder = sr.elder
                time_slots = TimeSlot.query.filter_by(schedule_result_id=sr.id).order_by(TimeSlot.time_order).all()
                grouped_schedules[elder] = {
                    'schedule_date': sr.schedule_date.isoformat(),
                    'json_data': sr.schedule_data,
                    'time_slots': [process_time_slot(ts) for ts in time_slots]
                }
            return jsonify(grouped_schedules)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

"""
测试成功-当天排班: http://192.168.10.29:10334/download_schedule/3449
测试成功-指定日期排班: http://192.168.10.29:10334/download_schedule/3449?date=2025-03-07
下载单个老人排班表路由 - 将指定老人的排班表导出为Excel文件
功能: 将特定老人的排班数据导出为Excel文件供下载
参数:
- elder: 老人ID(路径参数)
- date: 日期(可选, 默认今天)
返回: Excel文件下载
"""
@main.route('/download_schedule/<string:elder>', methods=['GET'])
def download_schedule(elder):
    schedule_date_str = request.args.get('date', date.today().isoformat())
    schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()

    schedule_result = ScheduleResult.query.filter(
        ScheduleResult.elder == elder,
        func.date(ScheduleResult.schedule_date) == schedule_date
    ).first()

    if not schedule_result:
        abort(404, description="Schedule not found")

    time_slots = TimeSlot.query.filter_by(schedule_result_id=schedule_result.id).order_by(TimeSlot.time_order).all()

    df = pd.DataFrame([(ts.time_slot, ts.elder, ts.activity, ts.activity_id, 'lack' if ts.caregiver_id == '-1' else ts.caregiver, ts.caregiver_id, ts.schedule_date) for ts in time_slots],
                      columns=['TimeSlot', 'Elder', 'Activity', 'ActivityId', 'Caregiver', 'CaregiverId', 'ScheduleDate'])

    excel_buffer = io.BytesIO()
    df.to_excel(excel_buffer, index=False)
    excel_buffer.seek(0)

    return send_file(
        excel_buffer,
        mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        as_attachment=True,
        download_name=f'{elder}_schedule_{schedule_date.isoformat()}.xlsx'
    )

"""
测试成功-下载指定日期的所有排班表: http://192.168.10.29:10334/download_all_schedules?date=2025-03-07
下载所有排班表路由 - 将所有老人的排班表打包成zip文件下载
功能: 将指定日期所有老人的排班数据导出为多个Excel文件并打包成zip文件
参数: date - 日期(可选, 默认今天)
返回: ZIP文件下载, 包含多个Excel文件
"""
@main.route('/download_all_schedules', methods=['GET'])
def download_all_schedules():
    schedule_date_str = request.args.get('date', date.today().isoformat())
    schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()
    schedule_results = ScheduleResult.query.filter(db.func.date(ScheduleResult.schedule_date) == schedule_date).all()

    if not schedule_results:
        abort(404, description="No schedules found for the specified date")

    memory_file = io.BytesIO()
    with zipfile.ZipFile(memory_file, 'w') as zf:
        for schedule_result in schedule_results:
            time_slots = TimeSlot.query.filter_by(schedule_result_id=schedule_result.id).order_by(TimeSlot.time_order).all()
            df = pd.DataFrame([(ts.time_slot, ts.activity, 'lack' if ts.caregiver_id == '-1' else ts.caregiver) for ts in time_slots],
                              columns=['TimeSlot', 'Activity', 'Caregiver'])
            excel_buffer = io.BytesIO()
            df.to_excel(excel_buffer, index=False)
            excel_buffer.seek(0)
            zf.writestr(f"{schedule_result.elder}_schedule.xlsx", excel_buffer.getvalue())

    memory_file.seek(0)

    return send_file(
        memory_file,
        mimetype='application/zip',
        as_attachment=True,
        download_name=f'all_schedules_{schedule_date.isoformat()}.zip'
    )

"""
获取护理动作列表路由 - 返回所有可用的护理动作
功能: 查询并返回系统中定义的所有护理动作
返回: 包含护理动作详情的JSON数组
"""
@main.route('/nursing_actions', methods=['GET'])
def get_nursing_actions():
    actions = DicNursingAction.query.all()
    return jsonify([{
        'id': action.id,
        'pid': action.pid,
        'name': action.name,
        'level': action.level,
        'nursing_level': action.nursing_level
    } for action in actions])

"""
获取老人列表路由 - 返回所有需要安排护理的老人(arrange='1')
功能: 查询并返回系统中所有需要排班的老人信息
返回: 包含老人信息的JSON数组, 只包括arrange='1'的老人
id: 记录ID
elder: 老人ID
actions: 老人需要的护理动作ID
arrange: 是否需要排班(值为'1'表示需要排班)
"""
@main.route('/elders', methods=['GET'])
def get_elders():
    elders = Elderdemand.query.filter_by(arrange='1').all()  # 只返回arrange为'1'的老人
    return jsonify([{
        'id': elder.id,
        'elder': elder.elder,
        'actions': elder.actions,
        'arrange': elder.arrange
    } for elder in elders])

"""
测试成功： http://192.168.10.29:10334/caregivers
获取护理人员列表路由 - 返回所有护理人员及其技能信息
功能: 查询并返回系统中所有护理人员的信息和技能
返回: 包含护理人员详情的JSON数组
"""
@main.route('/caregivers', methods=['GET'])
def get_caregivers():
    caregivers = Attendantskills.query.all()
    return jsonify([{
        'id': caregiver.id,
        'attendant_name': caregiver.attendant_name,
        'skills': caregiver.skills
    } for caregiver in caregivers])

"""
404错误处理路由 - 处理资源未找到的情况
功能: 自定义404错误响应, 返回JSON格式的错误信息
返回: 包含错误详情的JSON对象和404状态码
"""
@main.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': str(error)}), 404)

"""
应用初始化函数 - 注册蓝图和路由
功能: 将main蓝图注册到Flask应用
"""
def init_app(app):
    app.register_blueprint(main)

    # 通过POST请求到 /generate_and_save_schedule  生成新的调度并保存到数据库。
    # 通过GET请求到 /view_schedule查看保存的调度。
    # 通过GET请求到 /download_all_schedules或 /download_schedule/<elder_id> 下载保存的调度。

    # 照护计划id
    # 老人id
    # 时间段
    # 护理动作
    # 护理员
    # 更新时间

# =====================================================================
# 以下是前端页面路由，用于提供统一的管理界面
# 这些代码可以安全地删除，不会影响系统的核心功能
# =====================================================================

"""
前端管理界面路由 - 提供统一的Web界面访问所有API
功能: 返回一个HTML页面，整合所有API接口，方便系统管理和操作
返回: HTML页面
"""
@main.route('/dashboard')
def dashboard():
    return render_template('index.html')

"""
排班管理页面路由 - 提供排班管理界面
功能: 返回排班管理页面，用于查看和生成排班
返回: HTML页面
"""
@main.route('/schedule.html')
def schedule_page():
    return render_template('schedule.html')

"""
老人排班页面路由 - 提供老人排班查看界面
功能: 返回老人排班页面，用于查看特定老人的排班情况
返回: HTML页面
"""
@main.route('/elder.html')
def elder_page():
    return render_template('elder.html')

"""
护理人员排班页面路由 - 提供护理人员排班查看界面
功能: 返回护理人员排班页面，用于查看特定护理人员的排班情况
返回: HTML页面
"""
@main.route('/caregiver.html')
def caregiver_page():
    return render_template('caregiver.html')

# 如果需要删除上述前端功能，只需删除从"# ====="开始到此行的所有内容
# =====================================================================

"""
处理三班排班路由 - 将排班结果按三班制进行优化
功能：处理现有排班结果，分配三班制，处理跨天情况，支持多周期排班，预留应急资源
参数：
- start_date: 开始日期（可选，默认为当天）
- period_type: 周期类型（可选，默认为'day'，可选值：'day', 'week', 'month', 'quarter', 'year'）
- period_length: 周期长度（可选，默认为1）
- shift_start_time: 排班开始时间（可选，默认为'08:00'）
- day_night_weight: 白天/黑夜权重比（可选，默认为0.618）
返回：包含处理结果的JSON对象
"""
@main.route('/process_shift_schedule', methods=['POST'])
def process_shift_schedule():
    data = request.json or {}
    
    # 获取参数
    start_date_str = data.get('start_date')
    period_type = data.get('period_type')
    period_length = data.get('period_length')
    shift_start_time = data.get('shift_start_time')
    day_night_weight = data.get('day_night_weight')
    
    # 设置默认开始日期
    if start_date_str:
        try:
            start_date = datetime.strptime(start_date_str, "%Y-%m-%d").date()
        except ValueError:
            return jsonify({"error": "日期格式无效，请使用YYYY-MM-DD格式"}), 400
    else:
        start_date = date.today()
    
    # 创建配置参数副本
    config_params = params.copy()
    
    # 更新配置参数
    if period_type:
        config_params['schedule_period_type'] = period_type
    if period_length is not None:
        config_params['schedule_period_length'] = int(period_length)
    if shift_start_time:
        config_params['shift_start_time'] = shift_start_time
    if day_night_weight is not None:
        config_params['day_night_weight'] = float(day_night_weight)
    
    try:
        # 创建三班排班处理器
        shift_scheduler = ShiftScheduler(config_params)
        
        # 处理排班
        results = shift_scheduler.process_schedule(start_date)
        
        # 如果没有成功处理任何日期的排班
        if not any(result.get('status') == 'success' for result in results.values()):
            return jsonify({"warning": "没有可处理的排班数据或处理过程中出现错误", "results": results}), 200
        
        return jsonify({
            "message": "三班排班处理成功",
            "start_date": start_date.isoformat(),
            "config": {
                "period_type": config_params['schedule_period_type'],
                "period_length": config_params['schedule_period_length'],
                "shift_start_time": config_params['shift_start_time'],
                "day_night_weight": config_params['day_night_weight']
            },
            "results": results
        }), 200
    
    except Exception as e:
        return jsonify({"error": str(e)}), 500

"""
获取三班排班接口路由 - 获取特定日期的三班排班情况
功能：查询数据库中特定日期的三班排班结果
参数：
- date: 日期（可选，默认为当天）
返回：包含三班排班详情的JSON对象
"""
@main.route('/shift_schedule', methods=['GET'])
def get_shift_schedule():
    from .models import ShiftAssignment, TimeSlot
    
    schedule_date_str = request.args.get('date', date.today().isoformat())
    try:
        schedule_date = datetime.strptime(schedule_date_str, "%Y-%m-%d").date()
    except ValueError:
        return jsonify({"error": "日期格式无效，请使用YYYY-MM-DD格式"}), 400
    
    # 查询指定日期的班次分配
    shift_assignments = ShiftAssignment.query.filter(
        func.date(ShiftAssignment.schedule_date) == schedule_date
    ).all()
    
    if not shift_assignments:
        return jsonify({"error": "指定日期没有排班数据"}), 404
    
    # 获取所有相关的time_slots记录
    time_slot_ids = [sa.time_slot_id for sa in shift_assignments]
    time_slots = {ts.id: ts for ts in TimeSlot.query.filter(TimeSlot.id.in_(time_slot_ids)).all()}
    
    # 按班次分组
    shifts = {}
    for assignment in shift_assignments:
        shift_name = assignment.shift_name
        
        if shift_name not in shifts:
            shifts[shift_name] = {
                'slots': [],
                'caregivers': set(),
                'reserved_caregivers': set(),
                'is_night': assignment.is_night_shift,
                'start_hour': assignment.shift_start_hour,
                'end_hour': assignment.shift_end_hour
            }
        
        # 获取时间槽详情
        time_slot = time_slots.get(assignment.time_slot_id)
        if not time_slot:
            continue
        
        # 添加时间槽信息
        slot_info = {
            'time_slot': time_slot.time_slot,
            'elder': time_slot.elder,
            'activity': time_slot.activity,
            'caregiver': time_slot.caregiver,
            'caregiver_id': time_slot.caregiver_id,
            'is_reserved': assignment.is_reserved
        }
        shifts[shift_name]['slots'].append(slot_info)
        
        # 记录护理人员
        if assignment.caregiver_id != '-1':
            shifts[shift_name]['caregivers'].add(assignment.caregiver_id)
            if assignment.is_reserved:
                shifts[shift_name]['reserved_caregivers'].add(assignment.caregiver_id)
    
    # 将集合转换为列表，以便JSON序列化
    for shift_name in shifts:
        shifts[shift_name]['caregivers'] = list(shifts[shift_name]['caregivers'])
        shifts[shift_name]['reserved_caregivers'] = list(shifts[shift_name]['reserved_caregivers'])
    
    return jsonify({
        "date": schedule_date.isoformat(),
        "shifts": shifts
    }), 200

"""
连续执行排班生成和三班排班处理路由
功能：先执行排班生成，然后根据生成结果进行三班排班处理
参数：
- start_date: 开始日期（可选，默认为当天）
- period_type: 周期类型（可选，默认为'day'，可选值：'day', 'week', 'month', 'quarter', 'year'）
- period_length: 周期长度（可选，默认为1）
- shift_start_time: 排班开始时间（可选，默认为'08:00'）
- day_night_weight: 白天/黑夜权重比（可选，默认为0.618）
返回：包含完整处理结果的JSON对象
"""
@main.route('/generate_and_process_schedule', methods=['POST'])
def generate_and_process_schedule():
    try:
        # 1. 执行排班生成
        plan = Plan(params)
        client_schedules = plan.run()
        
        # 2. 从请求中获取三班排班的参数
        data = request.json or {}
        start_date_str = data.get('start_date')
        period_type = data.get('period_type')
        period_length = data.get('period_length')
        shift_start_time = data.get('shift_start_time')
        day_night_weight = data.get('day_night_weight')
        
        # 设置默认开始日期
        if start_date_str:
            try:
                start_date = datetime.strptime(start_date_str, "%Y-%m-%d").date()
            except ValueError:
                return jsonify({"error": "日期格式无效，请使用YYYY-MM-DD格式"}), 400
        else:
            start_date = date.today()
        
        # 创建配置参数副本
        config_params = params.copy()
        
        # 更新配置参数
        if period_type:
            config_params['schedule_period_type'] = period_type
        if period_length is not None:
            config_params['schedule_period_length'] = int(period_length)
        if shift_start_time:
            config_params['shift_start_time'] = shift_start_time
        if day_night_weight is not None:
            config_params['day_night_weight'] = float(day_night_weight)
        
        # 3. 执行三班排班处理
        shift_scheduler = ShiftScheduler(config_params)
        shift_results = shift_scheduler.process_schedule(start_date)
        
        # 4. 返回完整处理结果
        return jsonify({
            "message": "排班生成和三班处理成功完成",
            "generation_results": {
                "client_count": len(client_schedules) if client_schedules else 0,
                "date": datetime.now().isoformat()
            },
            "shift_processing": {
                "start_date": start_date.isoformat(),
                "config": {
                    "period_type": config_params['schedule_period_type'],
                    "period_length": config_params['schedule_period_length'],
                    "shift_start_time": config_params['shift_start_time'],
                    "day_night_weight": config_params['day_night_weight']
                },
                "results": shift_results
            }
        }), 200
        
    except Exception as e:
        return jsonify({"error": str(e)}), 500

"""
三班排班页面路由 - 显示三班排班管理界面
功能: 提供三班排班管理的Web界面
返回: 渲染的HTML页面
"""
@main.route('/shift_schedule.html')
def shift_schedule_page():
    return render_template('shift_schedule.html')

"""
新增老人需求接口
功能：添加新老人需求记录或更新现有记录
参数：
- elder: 老人ID
- actions: 需求活动列表，逗号分隔的ID
- arrange: 是否参与排班，'1'表示参与，'0'表示不参与
返回：成功或错误消息
"""
@main.route('/add_elder_demand', methods=['POST'])
def add_elder_demand():
    try:
        data = request.json
        elder = data.get('elder')
        actions = data.get('actions')
        arrange = data.get('arrange', '1')
        
        if not elder or not actions:
            return jsonify({"error": "老人ID和活动列表不能为空"}), 400
        
        # 查找是否已存在该老人记录
        elder_demand = Elderdemand.query.filter_by(elder=elder).first()
        
        if elder_demand:
            # 更新现有记录
            elder_demand.actions = actions
            elder_demand.arrange = arrange
        else:
            # 创建新记录
            elder_demand = Elderdemand(elder=elder, actions=actions, arrange=arrange)
            db.session.add(elder_demand)
        
        db.session.commit()
        return jsonify({"message": "老人需求添加/更新成功", "elder": elder}), 200
    
    except Exception as e:
        db.session.rollback()
        return jsonify({"error": str(e)}), 500

"""
控制老人参与护理员照护安排接口
功能：更新老人的排班参与状态
参数：
- elders: 老人ID列表
- arrange: 是否参与排班，'1'表示参与，'0'表示不参与
返回：成功或错误消息及更新的老人列表
"""
@main.route('/update_elder_arrangement', methods=['POST'])
def update_elder_arrangement():
    try:
        data = request.json
        elders = data.get('elders')
        arrange = data.get('arrange', '1')
        
        if not elders or not isinstance(elders, list):
            return jsonify({"error": "老人ID列表不能为空且必须是数组"}), 400
        
        updated_elders = []
        
        for elder_id in elders:
            elder_demand = Elderdemand.query.filter_by(elder=elder_id).first()
            
            if elder_demand:
                elder_demand.arrange = arrange
                updated_elders.append(elder_id)
        
        db.session.commit()
        
        status = "参与排班" if arrange == '1' else "不参与排班"
        return jsonify({
            "message": f"成功更新{len(updated_elders)}位老人为{status}",
            "updated_elders": updated_elders
        }), 200
    
    except Exception as e:
        db.session.rollback()
        return jsonify({"error": str(e)}), 500

"""
选择老人参与排班并记录接口
功能：选择指定老人参与本次排班，下次排班时自动排除
参数：
- elders: 老人ID列表
- include: 是否包含在排班中，true为包含，false为排除
返回：成功或错误消息及处理的老人列表
"""
@main.route('/select_elders_for_scheduling', methods=['POST'])
def select_elders_for_scheduling():
    try:
        data = request.json
        elders = data.get('elders')
        include = data.get('include', True)
        
        if not elders or not isinstance(elders, list):
            return jsonify({"error": "老人ID列表不能为空且必须是数组"}), 400
        
        processed_elders = []
        
        # 获取当前已处理的老人列表
        try:
            with open('scheduled_elders.json', 'r') as f:
                scheduled_data = json.load(f)
                scheduled_elders = set(scheduled_data.get('elders', []))
        except (FileNotFoundError, json.JSONDecodeError):
            scheduled_elders = set()
        
        # 处理包含或排除操作
        if include:
            scheduled_elders.update(elders)
            action = "包含"
        else:
            scheduled_elders = scheduled_elders - set(elders)
            action = "排除"
        
        # 保存更新后的列表
        with open('scheduled_elders.json', 'w') as f:
            json.dump({'elders': list(scheduled_elders)}, f)
        
        processed_elders = elders
        
        return jsonify({
            "message": f"成功{action}{len(processed_elders)}位老人进行排班",
            "processed_elders": processed_elders,
            "total_scheduled": len(scheduled_elders)
        }), 200
    
    except Exception as e:
        return jsonify({"error": str(e)}), 500

"""
查询三班排班结果接口
功能：获取指定日期的三班排班结果
参数：
- date: 查询日期，格式为YYYY-MM-DD，默认为今天
返回：包含三班排班详细信息的JSON对象
"""
@main.route('/query_shift_schedule', methods=['GET'])
def query_shift_schedule():
    try:
        # 获取日期参数
        query_date_str = request.args.get('date')
        
        # 设置默认日期为今天
        if query_date_str:
            try:
                query_date = datetime.strptime(query_date_str, "%Y-%m-%d").date()
            except ValueError:
                return jsonify({"error": "日期格式无效，请使用YYYY-MM-DD格式"}), 400
        else:
            query_date = date.today()
        
        # 查询指定日期的时间槽记录
        time_slots = TimeSlot.query.join(ScheduleResult).filter(
            func.date(ScheduleResult.schedule_date) == query_date
        ).all()
        
        # 解析结果，按班次分组
        shifts_data = {'早班': [], '中班': [], '晚班': []}
        
        for slot in time_slots:
            # 解析时间槽
            time_parts = slot.time_slot.split('-')[0]
            hour = int(time_parts.split(':')[0])
            
            # 根据时间判断班次
            shift_name = None
            if 6 <= hour < 14:
                shift_name = '早班'
            elif 14 <= hour < 22:
                shift_name = '中班'
            else:
                shift_name = '晚班'
            
            # 添加到对应班次
            shifts_data[shift_name].append({
                'elder': slot.elder,
                'time_slot': slot.time_slot,
                'activity': slot.activity,
                'caregiver': slot.caregiver,
                'schedule_date': slot.schedule_date.strftime('%Y-%m-%d')
            })
        
        # 计算统计信息
        stats = {
            '早班': {
                '时间段数': len(shifts_data['早班']),
                '老人数': len(set(slot['elder'] for slot in shifts_data['早班'])),
                '护理员数': len(set(slot['caregiver'] for slot in shifts_data['早班'] if slot['caregiver'] != '-'))
            },
            '中班': {
                '时间段数': len(shifts_data['中班']),
                '老人数': len(set(slot['elder'] for slot in shifts_data['中班'])),
                '护理员数': len(set(slot['caregiver'] for slot in shifts_data['中班'] if slot['caregiver'] != '-'))
            },
            '晚班': {
                '时间段数': len(shifts_data['晚班']),
                '老人数': len(set(slot['elder'] for slot in shifts_data['晚班'])),
                '护理员数': len(set(slot['caregiver'] for slot in shifts_data['晚班'] if slot['caregiver'] != '-'))
            }
        }
        
        return jsonify({
            "date": query_date.strftime('%Y-%m-%d'),
            "shifts": shifts_data,
            "statistics": stats
        }), 200
    
    except Exception as e:
        return jsonify({"error": str(e)}), 500

"""
三班制排班应用界面
功能：提供三班制排班管理的前端界面
返回：HTML页面
"""
@main.route('/three_shift_schedule.html')
def three_shift_schedule_page():
    return render_template('three_shift_schedule.html')
